package com.mebs.model.service.visa;

import com.mebs.model.Country;
import com.mebs.model.service.Service;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.jt.jet.util.JetUtils;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Mar 10, 2006, 6:39:35 PM
 */
@Entity()
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "VISA")
public class Visa extends Service {
    @ManyToOne(optional = false)
    @JoinColumn(name = "VisaTypeId")
    private VisaType type;

    @ManyToOne(optional = false)
    @JoinColumn(name = "CountryId")
    private Country visaCountry;

    @Column(name = "VisaExpiration", nullable = true)
    private Date visaExpiration;

    @Column(name = "StartDate", nullable = false)
    private Date startDate;


    @Column(name = "PassportName", nullable = true, length = 250)
    private String passportName;

    @ManyToOne(optional = false)
    @JoinColumn(name = "PassportCountryId")
    private Country passportCountry;

    @Column(name = "PassportNumber", nullable = true, length = 250)
    private String passportNumber;

    @Column(name = "PassportIssueDate", nullable = true)
    private Date passportIssueDate;

    @Column(name = "PassportReceivedDate", nullable = true)
    private Date passportReceivedDate;

    @Column(name = "PassportExpirationDate", nullable = true)
    private Date passportExpirationDate;


    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "VisaId")
    @OrderBy("plannedDate,actualDate,action")
    private Set<VisaProcess> processActions;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "VisaId")
    @OrderBy("completed,action")
    private Set<VisaMedical> medicalActions;

    @ManyToOne(optional = true)
    @JoinColumn(name = "VisaStatusId")
    private VisaStatus status;

    @Column(name = "CurrentStatusComments", nullable = true, length = 1024)
    private String currentStatusComments;

    @Column(name = "ApplicationSubmitted", nullable = true)
    private Date applicationSubmitted;

    @Column(name = "WorkPermitIssued", nullable = true)
    private Date workPermitIssued;

    @Column(name = "Approved", nullable = true)
    private Date approved;


    /**
     * ********************** Getters-setters ***********************
     */

    public VisaType getType()
    {
        return type;
    }

    public void setType(VisaType type)
    {
        this.type = type;
    }

    public Country getVisaCountry()
    {
        return visaCountry;
    }

    public void setVisaCountry(Country visaCountry)
    {
        this.visaCountry = visaCountry;
    }

    public Date getVisaExpiration()
    {
        return visaExpiration;
    }

    public void setVisaExpiration(Date visaExpiration)
    {
        this.visaExpiration = visaExpiration;
    }

    public String getPassportName()
    {
        return passportName;
    }

    public void setPassportName(String passportName)
    {
        this.passportName = passportName;
    }

    public Country getPassportCountry()
    {
        return passportCountry;
    }

    public void setPassportCountry(Country passportCountry)
    {
        this.passportCountry = passportCountry;
    }

    public String getPassportNumber()
    {
        return passportNumber;
    }

    public void setPassportNumber(String passportNumber)
    {
        this.passportNumber = passportNumber;
    }

    public Date getPassportIssueDate()
    {
        return passportIssueDate;
    }

    public void setPassportIssueDate(Date passportIssueDate)
    {
        this.passportIssueDate = passportIssueDate;
    }

    public Date getPassportExpirationDate()
    {
        return passportExpirationDate;
    }

    public void setPassportExpirationDate(Date passportExpirationDate)
    {
        this.passportExpirationDate = passportExpirationDate;
    }

    public Set<VisaProcess> getProcessActions()
    {
        return processActions;
    }

    public void setProcessActions(Set<VisaProcess> processActions)
    {
        this.processActions = processActions;
    }

    public Set<VisaMedical> getMedicalActions()
    {
        return medicalActions;
    }

    public void setMedicalActions(Set<VisaMedical> medicalActions)
    {
        this.medicalActions = medicalActions;
    }

    public VisaStatus getStatus()
    {
        return status;
    }

    public void setStatus(VisaStatus status)
    {
        this.status = status;
    }

    public String getCurrentStatusComments()
    {
        return currentStatusComments;
    }

    public void setCurrentStatusComments(String currentStatusComments)
    {
        this.currentStatusComments = currentStatusComments;
    }

    public Date getApplicationSubmitted()
    {
        return applicationSubmitted;
    }

    public void setApplicationSubmitted(Date applicationSubmitted)
    {
        this.applicationSubmitted = applicationSubmitted;
    }

    public Date getWorkPermitIssued()
    {
        return workPermitIssued;
    }

    public void setWorkPermitIssued(Date workPermitIssued)
    {
        this.workPermitIssued = workPermitIssued;
    }

    public Date getApproved()
    {
        return approved;
    }

    public void setApproved(Date approved)
    {
        this.approved = approved;
    }

    public Date getStartDate()
    {
        return startDate;
    }

    public void setStartDate(Date startDate)
    {
        this.startDate = startDate;
    }

    public Date getPassportReceivedDate()
    {
        return passportReceivedDate;
    }

    public void setPassportReceivedDate(Date passportReceivedDate)
    {
        this.passportReceivedDate = passportReceivedDate;
    }

    public boolean isVisaExpirationValid() {
        if(this.visaExpiration != null && this.passportExpirationDate != null) {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(this.visaExpiration);
            calendar.add(Calendar.MONTH,6);
            if(calendar.getTime().after(this.passportExpirationDate)) {
                return false;
            }
        }
        return true;
    }

    @Transient
    public Type getRequirementType()
    {
        return Type.VISA;
    }

    @Override
    public String toString()
    {
        return (this.getSequence() != null) ? this.getSequence().toString() : "";
    }

    @Transient
    public boolean isDeletable()
    {
        return JetUtils.isEmpty(processActions) &&
            JetUtils.isEmpty(medicalActions);
    }

    @Transient
    public String getSequenceNumber()
    {
        Calendar c = new GregorianCalendar();
        c.setTime(getStartDate());

        return String.format("VISA-%s-%05d-%02d%02d%02d",
            getCompany().getTicker() == null ? "XXX" : getCompany().getTicker(),
            getSequence(),
            c.get(Calendar.YEAR) % 100,
            c.get(Calendar.MONTH) + 1,
            c.get(Calendar.DAY_OF_MONTH));
    }

}
